package cn.nextProject.service.rayfile;

import cn.nextProject.configs.MinioConfig;
import cn.nextProject.entity.FileResult;
import io.minio.ListObjectsArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 共享网盘目录服务层
 */
@Slf4j
@Service
public class BucketService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;

    /**
     * 查询目录中中所有文件
     * @param bucketName 桶名称
     * @param pathName  目录路径名称
     * @return
     * @throws ServerException
     * @throws InsufficientDataException
     * @throws ErrorResponseException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws XmlParserException
     * @throws InternalException
     */
    @Cacheable(cacheNames = "bucketList",
            key = "(#bucketName) + '_' + " +
                    "(#pathName) + '_'")
    public List<FileResult> getFileList(String bucketName, String pathName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        List<FileResult> fileResultList = new ArrayList<>();
        //查询某一个目录下的所有文件
        Iterable<Result<Item>> rayfile = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(bucketName).prefix(pathName).recursive(false).build());

        for (Result<Item> itemResult : rayfile) {
            Item item = itemResult.get();
            boolean deleteMarker = item.isDeleteMarker();
            if (deleteMarker){
                log.info("该文件已被删除:{}", item.objectName());
                continue;
            }
            FileResult fileResult = new FileResult();
            fileResult.setBucketName(bucketName);
            int i = item.objectName().lastIndexOf("/");
            fileResult.setUrl(minioConfig.getEndpoint() + "/" + bucketName + "/" + item.objectName());
            fileResult.setName(item.objectName().substring(i+1));
            if (i == -1){
                fileResult.setLastPath(null);
            }else{
                fileResult.setLastPath(item.objectName().substring(0,i));
            }
            fileResult.setObjectName(item.objectName());
            fileResult.setSize(item.size());
            fileResult.setEtag(item.etag());
            if (item.owner() != null){
                fileResult.setOwnerId(item.owner().id());
                fileResult.setOwner(item.owner().displayName());
            }
            fileResult.setStorageClass(item.storageClass());
            fileResult.setDir(item.isDir());
            fileResult.setDeleteMarker(deleteMarker);
            fileResult.setLatest(item.isLatest());
            fileResult.setVersionId(item.versionId());
            if (!item.isDir()){
                fileResult.setModifyDateStr(simpleDateFormat.format(Date.from(item.lastModified().withZoneSameInstant(ZoneId.systemDefault()).toInstant())));
            }else{
                if (i > -1){
                    // 定位倒数第二个斜杠
                    int secondLastSlashIndex  = item.objectName().lastIndexOf('/', i - 1);
                    if (secondLastSlashIndex == -1) {
                        fileResult.setLastPath(null);
                        fileResult.setName(item.objectName().substring(0,i));
                    }else{
                        fileResult.setLastPath(item.objectName().substring(0,secondLastSlashIndex));
                        fileResult.setName(item.objectName().substring(secondLastSlashIndex+1,i));
                    }
                }
            }
            fileResultList.add(fileResult);
        }

        return fileResultList;
    }

    public static void main(String[] args) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        MinioClient minioClient= MinioClient.builder()
                //MinIO服务器访问网址端口
                .endpoint("http://127.0.0.1:9090")
                //MinIO服务器登录账号和密码
                .credentials("d9HY1uYo9JVtIaorrdUY","pQUOv9w6PFsm1c4ycvWwkt9BgXBtZ87NSe6VopK4")
                .build();
        Iterable<Result<Item>> rayfile = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket("rayfile").prefix(null).recursive(false)
                .build());


        for (Result<Item> itemResult : rayfile) {
            Item item = itemResult.get();
            String name = item.objectName();//文件名称
            long size = item.size(); //文件大小
            String modifyDateStr = null;
            String etag = item.etag(); //文件唯一标识
            String storageClass = item.storageClass();//存储类型
//            String owner = item.owner().displayName();//文件拥有者
            boolean isDir = item.isDir();//是否是目录
            boolean isDeleteMarker = item.isDeleteMarker();//是否是删除标记
            boolean isLatest = item.isLatest();//是否是最新
            String versionId = item.versionId();//版本id
            if (!isDir){
                ZonedDateTime zonedDateTime = item.lastModified();
                if (zonedDateTime != null){
                    Date modifyDate = Date.from(zonedDateTime.toInstant());//最后修改时间
                    modifyDateStr = simpleDateFormat.format(modifyDate);
                }
                log.info("文件名称：{}，文件大小：{}，最后修改时间：{}，文件唯一标识：{}，存储类型：{}，是否是目录：{}，是否是删除标记：{}，是否是最新：{}，版本id：{}",name,size,modifyDateStr,etag,storageClass,isDir,isDeleteMarker,isLatest,versionId);

            }else {
                log.info("文件名称：{}，文件大小：{}，最后修改时间：{}，文件唯一标识：{}，存储类型：{}，是否是目录：{}，是否是删除标记：{}，是否是最新：{}，版本id：{}",name,size,modifyDateStr,etag,storageClass,isDir,isDeleteMarker,isLatest,versionId);

                if (!isDeleteMarker){

                    Iterable<Result<Item>> rayfile1 = minioClient.listObjects(ListObjectsArgs.builder().bucket("rayfile").prefix(name).recursive(false).build());
                    for (Result<Item> itemResult1 : rayfile1) {
                        Item item1 = itemResult1.get();
                        String name1 = item1.objectName();//文件名称
                        long size1 = item1.size(); //文件大小
                        boolean dir = item1.isDir();
                        boolean deleteMarker = item1.isDeleteMarker();
                        String modifyDateStr1 = null;
                        if (!dir){
                            ZonedDateTime zonedDateTime1 = item1.lastModified();
                            if (zonedDateTime1 != null){
                                Date modifyDate1 = Date.from(zonedDateTime1.toInstant());//最后修改时间
                                modifyDateStr1 = simpleDateFormat.format(modifyDate1);
                            }
                        }

                        log.info("文件名称：{}，文件大小：{}，最后修改时间：{}",name1,size1,modifyDateStr1);
                    }
                }
            }

        }
    }
}
